//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package admin_events_api_serv

import (
	"context"

	"atomgit.com/openlinksaas/api-server/admin_api_serv/admin_common"
	"atomgit.com/openlinksaas/api-server/config"
	"atomgit.com/openlinksaas/api-server/dao"
	"atomgit.com/openlinksaas/api-server/dao/event_dao"
	"atomgit.com/openlinksaas/api-server/dao/project_dao"
	"atomgit.com/openlinksaas/api-server/dao/user_dao"
	"atomgit.com/openlinksaas/proto-gen-go.git/events_api"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/types/known/anypb"
)

type EventsAdminApiImpl struct {
	events_api.UnimplementedEventsAdminApiServer
	adminCfg *config.AdminCfg
}

func NewEventsAdminApiImpl(adminCfg *config.AdminCfg) *EventsAdminApiImpl {
	return &EventsAdminApiImpl{adminCfg: adminCfg}
}

func (apiImpl *EventsAdminApiImpl) ListProjectEv(ctx context.Context, req *events_api.AdminListProjectEvRequest) (*events_api.AdminListProjectEvResponse, error) {
	emptyList := []*events_api.Event{}

	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &events_api.AdminListProjectEvResponse{
			Code:      events_api.AdminListProjectEvResponse_CODE_WRONG_SESSION,
			ErrMsg:    "会话不存在",
			EventList: emptyList,
		}, nil
	}
	if !sess.AuthOk {
		return &events_api.AdminListProjectEvResponse{
			Code:      events_api.AdminListProjectEvResponse_CODE_NOT_AUTH,
			ErrMsg:    "未授权会话",
			EventList: emptyList,
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.ProjectPerm.AccessEvent {
		return &events_api.AdminListProjectEvResponse{
			Code:      events_api.AdminListProjectEvResponse_CODE_NO_PERMISSION,
			ErrMsg:    "没有权限",
			EventList: emptyList,
		}, nil
	}

	exist, err := project_dao.ProjectInfoDao.Exist(ctx, req.ProjectId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &events_api.AdminListProjectEvResponse{
			Code:      events_api.AdminListProjectEvResponse_CODE_NO_PROJECT,
			ErrMsg:    "项目不存在",
			EventList: emptyList,
		}, nil
	}
	if req.FilterByMemberUserId {
		exist, err = project_dao.MemberInfoDao.Exist(ctx, req.ProjectId, req.MemberUserId)
		if err != nil {
			return nil, err
		}
		if !exist {
			return &events_api.AdminListProjectEvResponse{
				Code:      events_api.AdminListProjectEvResponse_CODE_NO_MEMBER,
				ErrMsg:    "项目成员不存在",
				EventList: emptyList,
			}, nil
		}
	}

	count, err := event_dao.ProjectEventIndexDao.Count(ctx, req.ProjectId, req.FilterByMemberUserId, req.MemberUserId, req.FilterByTime, req.FromTime, req.ToTime, false)
	if err != nil {
		return nil, err
	}

	eventItemList, err := event_dao.ProjectEventIndexDao.List(ctx, req.ProjectId, req.FilterByMemberUserId, req.MemberUserId,
		false, req.FilterByTime, req.FromTime, req.ToTime, int64(req.Offset), int64(req.Limit), true)
	if err != nil {
		return nil, err
	}

	//获取事件
	eventIdList := []string{}
	for _, eventItem := range eventItemList {
		eventIdList = append(eventIdList, eventItem.EventId)
	}
	eventMap, err := event_dao.EventInfoDao.ListById(ctx, eventIdList)
	if err != nil {
		return nil, err
	}
	//获取用户信息
	userIdList := []string{}
	for _, eventItem := range eventItemList {
		userIdList = append(userIdList, eventItem.UserId)
	}
	userItemList, err := user_dao.UserInfoDao.ListById(ctx, userIdList)
	if err != nil {
		return nil, err
	}
	userItemMap := map[string]*user_dao.UserInfoDbItem{}
	for _, userItem := range userItemList {
		userItemMap[userItem.UserId] = userItem
	}
	//组装结果
	evList := []*events_api.Event{}
	for _, eventItem := range eventItemList {
		eventData, ok := eventMap[eventItem.EventId]
		if !ok {
			continue
		}
		eventObj := &anypb.Any{}
		err = proto.Unmarshal(eventData.EventData, eventObj)
		if err != nil {
			return nil, err
		}
		displayName := ""
		logoUri := ""
		userItem, ok := userItemMap[eventItem.UserId]
		if ok {
			displayName = userItem.BasicInfo.DisplayName
			logoUri = userItem.BasicInfo.LogoUri
		}
		evList = append(evList, eventItem.ToEvent(eventObj, displayName, logoUri))
	}

	return &events_api.AdminListProjectEvResponse{
		Code:       events_api.AdminListProjectEvResponse_CODE_OK,
		TotalCount: count,
		EventList:  evList,
	}, nil
}
